home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #5 / Amiga Plus CD - 2000 - No. 5.iso / Tools / Dev / FPSE_src / system / amiga / plugin / gpu / poly2.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-01  |  36.4 KB  |  1,565 lines

  1. #include "gpulocal.h"
  2.  
  3. #define SUPPORT_ALPHA
  4.  
  5. #define   CMASK0    (0x1f)
  6. #define   CMASK1    (0x1f<<5)
  7. #define   CMASK2    (0x1f<<10)
  8. #define   CMASKL0   (0x3f)
  9. #define   CMASKL1   (0x3f<<11)
  10. #define   CMASKL2   (0x3e<<21)
  11.  
  12. #define   CMASK     (~((1<<15)|(1<<10)|(1<<5)))
  13. #define   CMASKL    (~((1<<31)|(1<<10)|(1<<21)))
  14. #define   COLPACK(c)     ((c)&CMASK1)|(((c)>>16)&(CMASK0|CMASK2))
  15. #define   RGB2COL(r,g,b) (((r)<<23)|((b)<<13)|((g)<<2))
  16. /* 0rrrrrxxxx0bbbbbxxxxx0gggggxxxxx -> 0rrrrrgggggbbbbb */
  17. /* |       |       |       |       | */
  18. /* r=1bit­‚È‚¢ */
  19. #define   COLUNPACK(c)   ((c)&CMASK1)|(((c)&(CMASK0|CMASK2))<<16)
  20. /* 0rrrrrgggggbbbbb -> 0rrrrr00000bbbbb000000ggggg00000 */
  21.  
  22. #define   FIX_BIT   10
  23. #define   FIX_1     (1<<FIX_BIT)
  24. #define   I2F(a)    ((a)<<FIX_BIT)
  25. #define   F2I(a)    ((a)>>FIX_BIT)
  26. #define   F4I(a)    (((a)>>FIX_BIT) & 0xFF)
  27.  
  28. static EDGE edge[512*2];
  29.  
  30. static int masktbl[2048];
  31.  
  32. #define   VRAMADR(x,y)   vram + (x) + (y)*FRAME_W
  33.  
  34. static void EdgeF(POINT_F *p0,POINT_F *p1,EDGE *edge)
  35. {
  36.      int dy;
  37.      INT32 x,dx;
  38.  
  39.      dy = p1->y - p0->y;
  40.      if (dy==0) return;
  41.      if (dy<0) {
  42.           /* right */
  43.           void *t;
  44.           t = p0; p0=p1; p1=t;
  45.           dy = -dy;
  46.      } else {
  47.           /* left */
  48.           edge++;
  49.      }
  50.  
  51.      edge+=p0->y*2;
  52.      x = I2F(p0->x);
  53.      dx = I2F(p1->x - p0->x)/dy;
  54.  
  55.      /* clip */
  56.      if (p1->y<YMIN || p0->y>=YMAX) return;
  57.      if (p0->y<YMIN) {
  58.           int ddy = YMIN - p0->y;
  59.           x += dx*ddy;
  60.           edge +=ddy*2;
  61.           if ((dy-=ddy) <= 0) return;
  62.      }
  63.      if (p1->y>=YMAX) {
  64.           dy += YMAX - p1->y;
  65.      }
  66.  
  67.      do {
  68.           edge->x = x; x+=dx;
  69.           edge+=2;
  70.      } while(--dy);
  71. }
  72.  
  73. static void EdgeFT(POINT_FT *p0,POINT_FT *p1,EDGE *edge)
  74. {
  75.      int dy;
  76.      INT32 x,u,v,dx,du,dv;
  77.  
  78.      dy = p1->y - p0->y;
  79.      if (dy==0) return;
  80.      if (dy<0) {
  81.           /* right */
  82.           void *t;
  83.           t = p0; p0=p1; p1=t;
  84.           dy = -dy;
  85.      } else {
  86.           /* left */
  87.           edge++;
  88.      }
  89.  
  90.      edge+=p0->y*2;
  91.      x = I2F(p0->x);
  92.      u = I2F(p0->u);
  93.      v = I2F(p0->v);
  94.      dx = I2F(p1->x - p0->x)/dy;
  95.      du = I2F(p1->u - p0->u)/dy;
  96.      dv = I2F(p1->v - p0->v)/dy;
  97.  
  98.      /* clip */
  99.      if (p1->y<YMIN || p0->y>=YMAX) return;
  100.      if (p0->y<YMIN) {
  101.           int ddy = YMIN - p0->y;
  102.           x += dx*ddy;
  103.           u += du*ddy;
  104.           v += dv*ddy;
  105.           edge +=ddy*2;
  106.           if ((dy-=ddy) <= 0) return;
  107.      }
  108.      if (p1->y>=YMAX) {
  109.           dy += YMAX - p1->y;
  110.      }
  111.  
  112.      do {
  113.           edge->x = x; x+=dx;
  114.           edge->u = u; u+=du;
  115.           edge->v = v; v+=dv;
  116.           edge+=2;
  117.      } while(--dy);
  118. }
  119.  
  120. #define   ADDCOL(c,dc)            c.r+=dc.r; c.g+=dc.g; c.b+=dc.b
  121. #define   ADDMULCOL(c,dc,m)   c.r+=dc.r*m; c.g+=dc.g*m; c.b+=dc.b*m
  122. #define   CALCDC(dc,c0,c1,d)  dc.r=(c1.r-c0.r)/d;dc.g=(c1.g-c0.g)/d;dc.b=(c1.b-c0.b)/d
  123. #define   COLOR2LCOLOR(lc,c)  lc.r=I2F(c.r);lc.g=I2F(c.g);lc.b=I2F(c.b)
  124.  
  125. #define   COLOR2PIXEL(c) ((overtbl[c.r>>2]<<10)|(overtbl[c.g>>2]<<5)|(overtbl[c.b>>2]))
  126. #define   LCOL2PIXEL(c)  ((overtbl[F2I(c.r)>>2]<<10)|(overtbl[F2I(c.g)>>2]<<5)|(overtbl[F2I(c.b)>>2]))
  127.  
  128. static unsigned int spctbl[32*2] = {
  129.       0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
  130.      16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
  131.      31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
  132.      31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
  133. };
  134.  
  135. #define   MULCOL(c,c0) (\
  136.      (spctbl[(((c>>10)&31)*c0.b)>>(FIX_BIT+7)]<< 10) | \
  137.      (spctbl[(((c>> 5)&31)*c0.g)>>(FIX_BIT+7)]<< 5) | \
  138.      (spctbl[(((c&31)    )*c0.r)>>(FIX_BIT+7)]) )
  139.  
  140. static unsigned int overtbl[32*2] = {
  141.       0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
  142.       8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,
  143.      16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,
  144.      24,24,25,25,26,26,27,27,28,28,29,29,30,30,31,31
  145. };
  146.  
  147. static void EdgeG(POINT_G *p0,POINT_G *p1,EDGE *edge)
  148. {
  149.      int  dy;
  150.      INT32  x,dx;
  151.      LCOLOR c0,c1,dc;
  152.  
  153.      dy = p1->y - p0->y;
  154.      if (dy==0) return;
  155.      if (dy<0) {
  156.           /* right */
  157.           void *t;
  158.           t = p0; p0=p1; p1=t;
  159.           dy = -dy;
  160.      } else {
  161.           /* left */
  162.           edge++;
  163.      }
  164.  
  165.      edge+=p0->y*2;
  166.      x = I2F(p0->x);
  167.      dx = I2F(p1->x - p0->x)/dy;
  168.      COLOR2LCOLOR(c0,p0->c);
  169.      COLOR2LCOLOR(c1,p1->c);
  170.      CALCDC(dc,c0,c1,dy);
  171.  
  172.      /* clip */
  173.      if (p1->y<YMIN || p0->y>=YMAX) return;
  174.      if (p0->y<YMIN) {
  175.           int ddy = YMIN - p0->y;
  176.           x += dx*ddy;
  177.           ADDMULCOL(c0,dc,ddy);
  178.           edge +=ddy*2;
  179.           if ((dy-=ddy) <= 0) return;
  180.      }
  181.      if (p1->y>=YMAX) {
  182.           dy += YMAX - p1->y;
  183.      }
  184.  
  185.      do {
  186.           edge->x = x; x+=dx;
  187.           edge->c = c0; ADDCOL(c0,dc);
  188.           edge+=2;
  189.      } while(--dy);
  190. }
  191.  
  192. static void EdgeGT(POINT_GT *p0,POINT_GT *p1,EDGE *edge)
  193. {
  194.      int  dy;
  195.      INT32  x,u,v,dx,du,dv;
  196.      LCOLOR c0,c1,dc;
  197.  
  198.      dy = p1->y - p0->y;
  199.      if (dy==0) return;
  200.      if (dy<0) {
  201.           /* right */
  202.           void *t;
  203.           t = p0; p0=p1; p1=t;
  204.           dy = -dy;
  205.      } else {
  206.           /* left */
  207.           edge++;
  208.      }
  209.  
  210.      edge+=p0->y*2;
  211.      x = I2F(p0->x);
  212.      u = I2F(p0->u);
  213.      v = I2F(p0->v);
  214.      dx = I2F(p1->x - p0->x)/dy;
  215.      du = I2F(p1->u - p0->u)/dy;
  216.      dv = I2F(p1->v - p0->v)/dy;
  217.  
  218.      COLOR2LCOLOR(c0,p0->c);
  219.      COLOR2LCOLOR(c1,p1->c);
  220.      CALCDC(dc,c0,c1,dy);
  221.  
  222.      /* clip */
  223.      if (p1->y<YMIN || p0->y>=YMAX) return;
  224.      if (p0->y<YMIN) {
  225.           int ddy = YMIN - p0->y;
  226.           x += dx*ddy;
  227.           u += du*ddy;
  228.           v += dv*ddy;
  229.           ADDMULCOL(c0,dc,ddy);
  230.           edge +=ddy*2;
  231.           if ((dy-=ddy) <= 0) return;
  232.      }
  233.      if (p1->y>=YMAX) {
  234.           dy += YMAX - p1->y;
  235.      }
  236.  
  237.      do {
  238.           edge->x = x; x+=dx;
  239.           edge->u = u; u+=du;
  240.           edge->v = v; v+=dv;
  241.           edge->c = c0; ADDCOL(c0,dc);
  242.           edge+=2;
  243.      } while(--dy);
  244. }
  245.  
  246. #define   ALIGN4(adr)    (((UINT32)(adr)&3)==0)
  247.  
  248. static void _hline(INT16 *p,int dx,int c)
  249. {
  250.      if (!ALIGN4(p)) { *p++=c; dx--; }
  251.      for(;dx>=2;dx-=2) { *((long*)p)++= c; }
  252.      if (dx) *p++=c;
  253. }
  254.  
  255. void DrawInit(void)
  256. {
  257.     int i;
  258.  
  259.     for(i=0;i<2048;i++) {
  260.         int mask = 0;
  261.         if (i&1      ) mask |= 31;
  262.         if (i&(1<<5) ) mask |= 31<<5;
  263.         if (i&(1<<10)) mask |= 31<<10;
  264.         masktbl[i] = mask;
  265.     }
  266. }
  267.  
  268. #define   BITMODE   (3*4)
  269. #define   ABRFLG    (2*16)
  270. #define   BIT4 0
  271. #define   BIT8 (1*4)
  272. #define   BIT15     (2*4)
  273. #define   T50      0|ABRFLG
  274. #define   T100 1|ABRFLG
  275. #define   T100m     2|ABRFLG
  276. #define   T25      3|ABRFLG
  277. #define   NOSHADE   (1*16)
  278.  
  279. #define   TEXEL15(tex,u,v)    tex[F4I(u)+F4I(v)*256];
  280.  
  281. #define   ALPHA50(cc,c2) cc = ((cc&CMASK)+(c2&CMASK))/2
  282. #define   ALPHA100(cc,c2)     { \
  283.      cc = (cc&CMASK) + (c2&CMASK); \
  284.      cc = (cc&CMASK) | masktbl[cc>>5]; }
  285. #define   ALPHA100m(cc,c2) { \
  286.      cc = (c2|~CMASK) - (cc&CMASK); \
  287.      cc = (cc&CMASK) & ~masktbl[cc>>5]; }
  288. #define   ALPHA25(cc,c2) { \
  289.      /* 1100011000111 */ \
  290.      cc = ((cc>>2)&0x18c7) + (c2&CMASK); \
  291.      cc = (cc&CMASK) | masktbl[cc>>5]; }
  292.  
  293. void DrawF(EDGE *edge,int ymin,int ymax,unsigned int c)
  294. {
  295.      int dx,dy;
  296.      INT16 *p,*p0;
  297.  
  298.      if ((dy = ymax-ymin) <= 0) return;
  299.      p0 = VRAMADR(0,ymin);
  300.      edge += ymin*2;
  301.      c |= (c<<16);
  302.      do {
  303.           dx = F2I(edge[1].x)-F2I(edge[0].x);
  304.           if (dx) {
  305.                p = p0+F2I(edge[0].x);
  306.                if (F2I(edge[0].x)<XMIN) {
  307.                     int d = XMIN-F2I(edge[0].x);
  308.                     p+=d;
  309.                     dx-=d;
  310.                }
  311.                if (F2I(edge[1].x)>XMAX) {
  312.                     dx -= F2I(edge[1].x)-XMAX;
  313.                }
  314.                if (dx>0) {
  315.                     if (!ALIGN4(p)) *p++=c;
  316.                     for(;dx>=2;dx-=2) { *((long*)p)++= c; }
  317.                     if (dx) *p++=c;
  318.                }
  319.           }
  320.           edge+=2;
  321.           p0+=FRAME_W;
  322.      } while(--dy);
  323.     toUpdate = 1;
  324. }
  325.  
  326. #define   G_HLINE_A(ALPHA) \
  327.                     do { \
  328.                          int c2 = MULCOL(*p,c0); \
  329.                          ALPHA(c2,*p); \
  330.                          *p=c2; \
  331.                          p++; \
  332.                          ADDCOL(c0,dc); \
  333.                     } while(--dx)
  334.  
  335. void DrawG(EDGE *edge,int ymin,int ymax,int code)
  336. {
  337.      int dx,dy,mode;
  338.      INT16 *p,*p0;
  339.      LCOLOR c0,dc;
  340.  
  341.      if ((dy = ymax-ymin) <= 0) return;
  342.      p0 = VRAMADR(0,ymin);
  343.      edge += ymin*2;
  344.      mode = ((gpu.tpage>>5)&3)|((code&2)*16);
  345.      do {
  346.           dx = F2I(edge[1].x)-F2I(edge[0].x);
  347.           if (dx > 0) {
  348.                CALCDC(dc,edge[0].c,edge[1].c,dx);
  349.                c0 = edge[0].c;
  350.                p = p0+F2I(edge[0].x);
  351.                if (F2I(edge[0].x)<XMIN) {
  352.                     int d = XMIN-F2I(edge[0].x);
  353.                     c0.r+=dc.r*d;
  354.                     c0.g+=dc.g*d;
  355.                     c0.b+=dc.b*d;
  356.                     p+=d;
  357.                     dx-=d;
  358.                }
  359.                if (F2I(edge[1].x)>XMAX) {
  360.                     dx -= F2I(edge[1].x)-XMAX;
  361.                }
  362.                if (dx>0)
  363.                     switch (mode) {
  364.                     case T50:
  365.                          G_HLINE_A(ALPHA50);
  366.                          break;
  367.                     case T100:
  368.                          G_HLINE_A(ALPHA100);
  369.                          break;
  370.                     case T100m:
  371.                          G_HLINE_A(ALPHA100m);
  372.                          break;
  373.                     case T25:
  374.                          G_HLINE_A(ALPHA25);
  375.                          break;
  376.                     default:
  377.                          do {
  378.                               *p++= LCOL2PIXEL(c0);
  379.                               ADDCOL(c0,dc);
  380.                          } while(--dx);
  381.                          break;
  382.                     }
  383.           }
  384.           edge+=2;
  385.           p0+=FRAME_W;
  386.      } while(--dy);
  387.     toUpdate = 1;
  388. }
  389.  
  390. #define   FT_HLINE(TEXEL) \
  391.                     do { \
  392.                          int c = TEXEL(tex,u,v); \
  393.                          if (c) *p=c; \
  394.                          p++; u +=du; v+=dv; \
  395.                     } while(--dx)
  396.  
  397. #define   FT_HLINE_A(TEXEL,ALPHA) \
  398.                     do { \
  399.                          int c = TEXEL(tex,u,v); \
  400.                          if (c) { \
  401.                               if (c&0x8000) ALPHA(c,*p); \
  402.                               *p = c; \
  403.                          } \
  404.                          p++; u += du; v+=dv; \
  405.                     } while(--dx)
  406.  
  407. #define   FT_HLINE_A15(TEXEL,ALPHA) \
  408.                     do { \
  409.                          int c = TEXEL(tex,u,v); \
  410.                          if (c) { \
  411.                               int c2 = MULCOL(c,c0); \
  412.                               if (c&0x8000) ALPHA(c2,*p); \
  413.                               *p = c2; \
  414.                          } \
  415.                          p++; u +=du; v+=dv; \
  416.                     } while(--dx)
  417.  
  418.  
  419. #define   GT_HLINE(TEXEL) \
  420.                     do { \
  421.                          int c = TEXEL(tex,u,v); \
  422.                          if (c) *p=MULCOL(c,c0); \
  423.                          p++; u +=du; v+=dv; \
  424.                          ADDCOL(c0,dc); \
  425.                     } while(--dx)
  426.  
  427. #define   GT_HLINE_A(TEXEL,ALPHA) \
  428.                     do { \
  429.                          int c = TEXEL(tex,u,v); \
  430.                          if (c) { \
  431.                               int c2 = MULCOL(c,c0); \
  432.                               if (c&0x8000) ALPHA(c2,*p); \
  433.                                                 *p=c2; \
  434.                          } \
  435.                          p++; u +=du; v+=dv; \
  436.                          ADDCOL(c0,dc); \
  437.                     } while(--dx)
  438.  
  439. void DrawFT(EDGE *edge,int ymin,int ymax,int tpage,int clut,COLOR c0code)
  440. {
  441.      int dx,dy,mode;
  442.      INT16 *p0;
  443.      INT16 *tex;
  444.      LCOLOR c0;
  445.  
  446.         if (ymin > YMAX) return;
  447.         if (ymax < YMIN) return;
  448.         if (ymin < YMIN) ymin = YMIN;
  449.         if (ymax > YMAX) ymax = YMAX;
  450.  
  451.      if ((dy = ymax-ymin) <= 0) return;
  452.  
  453.      if (c0code.r==0x80 && c0code.g==0x80 && c0code.b==0x80)
  454.           c0code.code|=1; /* NOSHADE */
  455.  
  456.      p0 = VRAMADR(0,ymin);
  457.      edge += ymin*2;
  458.      tex = get_texture(tpage,clut);
  459.      mode = ((tpage>>5)&3)|((c0code.code&3)*16);
  460.  
  461.      if (!(mode&NOSHADE))
  462.           COLOR2LCOLOR(c0,c0code);
  463.  
  464.      do {
  465.           dx = F2I(edge[1].x)-F2I(edge[0].x);
  466.           if (dx > 0) {
  467.                INT32 u,v,du,dv;
  468.                INT16 *p;
  469.  
  470.                u = edge[0].u;
  471.                v = edge[0].v;
  472.                du = (edge[1].u-edge[0].u)/dx;
  473.                dv = (edge[1].v-edge[0].v)/dx;
  474.                p = p0+F2I(edge[0].x);
  475.                if (F2I(edge[0].x)<XMIN) {
  476.                     int d = XMIN-F2I(edge[0].x);
  477.                     p+=d;
  478.                     u = u+du*d;
  479.                     v = v+dv*d;
  480.                     dx-=d;
  481.                }
  482.                if (F2I(edge[1].x)>XMAX) {
  483.                     dx -= F2I(edge[1].x)-XMAX;
  484.                }
  485.                if (dx>0)
  486.                switch(mode) {
  487.                case T50|NOSHADE:
  488.                     FT_HLINE_A(TEXEL15,ALPHA50);
  489.                     break;
  490.                case T100|NOSHADE:
  491.                     FT_HLINE_A(TEXEL15,ALPHA100);
  492.                     break;
  493.                case T100m|NOSHADE:
  494.                     FT_HLINE_A(TEXEL15,ALPHA100m);
  495.                     break;
  496.                case T25|NOSHADE:
  497.                     FT_HLINE_A(TEXEL15,ALPHA25);
  498.                     break;
  499.  
  500.                case T50:
  501.                     FT_HLINE_A15(TEXEL15,ALPHA50);
  502.                     break;
  503.                case T100:
  504.                     FT_HLINE_A15(TEXEL15,ALPHA100);
  505.                     break;
  506.                case T100m:
  507.                     FT_HLINE_A15(TEXEL15,ALPHA100m);
  508.                     break;
  509.                case T25:
  510.                     FT_HLINE_A15(TEXEL15,ALPHA25);
  511.                     break;
  512.                default:
  513.                     if (mode & NOSHADE) FT_HLINE(TEXEL15);
  514.                     else
  515.                     do {
  516.                          int c = TEXEL15(tex,u,v);
  517.                          if (c&0x7FFF) *p=MULCOL(c,c0);
  518.                          p++; u +=du; v+=dv;
  519.                     } while(--dx);
  520.  
  521.                     break;
  522.                }
  523.           }
  524.           edge+=2;
  525.           p0+=FRAME_W;
  526.      } while(--dy);
  527.     toUpdate = 1;
  528. }
  529.  
  530. void DrawGT(EDGE *edge,int ymin,int ymax,int tpage,int clut,int code)
  531. {
  532.      int dx,dy,mode;
  533.      INT32 u,v,du,dv;
  534.      INT16 *p,*p0;
  535.      INT16 *tex;
  536.      LCOLOR c0,dc;
  537.  
  538.         if (ymin > YMAX) return;
  539.         if (ymax < YMIN) return;
  540.         if (ymin < YMIN) ymin = YMIN;
  541.         if (ymax > YMAX) ymax = YMAX;
  542.  
  543.      if ((dy = ymax-ymin) <= 0) return;
  544.      p0 = vram+ymin*FRAME_W;
  545.      edge += ymin*2;
  546.  
  547.      tex = get_texture(tpage,clut);
  548.      mode = ((tpage>>5)&3)|((code&3)*16);
  549.  
  550.      do {
  551.           dx = F2I(edge[1].x)-F2I(edge[0].x);
  552.           if (dx > 0) {
  553.                u = edge[0].u;
  554.                v = edge[0].v;
  555.                du = (edge[1].u-edge[0].u)/dx;
  556.                dv = (edge[1].v-edge[0].v)/dx;
  557.                p = p0+F2I(edge[0].x);
  558.                CALCDC(dc,edge[0].c,edge[1].c,dx);
  559.                c0 = edge[0].c;
  560.                if (F2I(edge[0].x)<XMIN) {
  561.                     int d = XMIN-F2I(edge[0].x);
  562.                     p+=d;
  563.                     u+=du*d;
  564.                     v+=dv*d;
  565.                     c0.r+=dc.r*d;
  566.                     c0.g+=dc.g*d;
  567.                     c0.b+=dc.b*d;
  568.                     dx-=d;
  569.                }
  570.                if (F2I(edge[1].x)>XMAX) {
  571.                     dx -= F2I(edge[1].x)-XMAX;
  572.                }
  573.                if (dx>0)
  574.                switch(mode) {
  575.                case T50:
  576.                     GT_HLINE_A(TEXEL15,ALPHA50);
  577.                     break;
  578.                case T100:
  579.                     GT_HLINE_A(TEXEL15,ALPHA100);
  580.                     break;
  581.                case T100m:
  582.                     GT_HLINE_A(TEXEL15,ALPHA100m);
  583.                     break;
  584.                case T25:
  585.                     GT_HLINE_A(TEXEL15,ALPHA25);
  586.                     break;
  587.                default:
  588.                     GT_HLINE(TEXEL15);
  589.                                 break;
  590.                }
  591.           }
  592.           edge+=2;
  593.           p0+=FRAME_W;
  594.      } while(--dy);
  595.     toUpdate = 1;
  596. }
  597.  
  598. #define   ABS(x)  (((x)>0)?(x):-(x))
  599.  
  600. #define FX(yy)   (yy*dx/dy - x)
  601. #define FY(xx)   (xx*dy/dx - y)
  602.  
  603. void DrawLineF(POINT_F *p0,POINT_F *p1,int c)
  604. {
  605.      int x,y,dx,dy;
  606.      INT16 *p;
  607.  
  608. // printf("old: %d %d %d %d\n",p0->x,p0->y,p1->x,p1->y);
  609.      dx = p1->x - p0->x;
  610.         y=1;
  611.         if (dx<0) y = -1;
  612.         dx += y;
  613.  
  614.      dy = p1->y - p0->y;
  615.         y=1;
  616.         if (dy<0) y = -1;
  617.         dy += y;
  618.  
  619. // CLIPPING
  620.         x = p0->y*dx/dy - p0->x;
  621.         y = p0->x*dy/dx - p0->y;
  622.  
  623.         if (p0->y < YMIN) {     // p0
  624.             p0->x = FX(YMIN);
  625.             p0->y = YMIN;
  626.         } else
  627.         if (p0->y > YMAX) {
  628.             p0->x = FX(YMAX);
  629.             p0->y = YMAX;
  630.         }
  631.         if (p0->x < XMIN) {
  632.             p0->y = FY(XMIN);
  633.             p0->x = XMIN;
  634.         } else
  635.         if (p0->x > XMAX) {
  636.             p0->y = FY(XMAX);
  637.             p0->x = XMAX;
  638.         }
  639.         if (p1->y < YMIN) {     // p1
  640.             p1->x = FX(YMIN);
  641.             p1->y = YMIN;
  642.         } else
  643.         if (p1->y > YMAX) {
  644.             p1->x = FX(YMAX);
  645.             p1->y = YMAX;
  646.         }
  647.         if (p1->x < XMIN) {
  648.             p1->y = FY(XMIN);
  649.             p1->x = XMIN;
  650.         } else
  651.         if (p1->x > XMAX) {
  652.             p1->y = FY(XMAX);
  653.             p1->x = XMAX;
  654.         }
  655. // printf("new: %d %d %d %d\n",p0->x,p0->y,p1->x,p1->y);
  656.         if (p0->x > XMAX || p0->x < XMIN) return;
  657.         if (p1->x > XMAX || p1->x < XMIN) return;
  658.         if (p0->y > YMAX || p0->y < YMIN) return;
  659.         if (p1->y > YMAX || p1->y < YMIN) return;
  660.  
  661. // Recalculate variations
  662.      dx = p1->x - p0->x;
  663.      dy = p1->y - p0->y;
  664.  
  665. // Drawing
  666.      if (ABS(dx)<=ABS(dy)) {
  667.           if (dy<0) {
  668.                void *t;
  669.                t=p0;p0=p1;p1=t;
  670.                dy = -dy;
  671.                         dx = -dx;
  672.           }
  673.                 dy++;
  674.           dx = I2F(dx)/dy;
  675.           x = I2F(p0->x);
  676.           y = p0->y;
  677.  
  678.           p = vram+y*FRAME_W;
  679.           do {
  680.                p[F2I(x)] = c; x+=dx;
  681.                p+=FRAME_W;
  682.           } while(--dy);
  683.      } else {
  684.           if (dx<0) {
  685.                void *t;
  686.                t=p0;p0=p1;p1=t;
  687.                dx = -dx;
  688.                         dy = -dy;
  689.           }
  690.                 dx++;
  691.           dy = I2F(dy)/dx;
  692.  
  693.           x = p0->x;
  694.           y = I2F(p0->y);
  695.  
  696.           p = vram+x;
  697.           do {
  698.                p[F2I(y)*FRAME_W] = c; y+=dy;
  699.                p++;
  700.           } while(--dx);
  701.      }
  702.     toUpdate = 1;
  703. }
  704.  
  705. //int ct=0;
  706. void DrawLineG(POINT_G *p0,POINT_G *p1)
  707. {
  708.      int x,y,dx,dy;
  709.      INT16 *p;
  710.      LCOLOR    c0,c1,dc;
  711.  
  712.      dx = p1->x - p0->x;
  713.         y=1;
  714.         if (dx<0) y = -1;
  715.         dx += y;
  716.  
  717.      dy = p1->y - p0->y;
  718.         y=1;
  719.         if (dy<0) y = -1;
  720.         dy += y;
  721.  
  722. // CLIPPING
  723.         x = p0->y*dx/dy - p0->x;
  724.         y = p0->x*dy/dx - p0->y;
  725.  
  726. //printf("%d) old: %d %d %d %d\n",ct,p0->x,p0->y,p1->x,p1->y);
  727.         if (p0->y < YMIN) {     // p0
  728.             p0->x = FX(YMIN);
  729.             p0->y = YMIN;
  730.         } else
  731.         if (p0->y > YMAX) {
  732.             p0->x = FX(YMAX);
  733.             p0->y = YMAX;
  734.         }
  735.         if (p0->x < XMIN) {
  736.             p0->y = FY(XMIN);
  737.             p0->x = XMIN;
  738.         } else
  739.         if (p0->x > XMAX) {
  740.             p0->y = FY(XMAX);
  741.             p0->x = XMAX;
  742.         }
  743.         if (p1->y < YMIN) {     // p1
  744.             p1->x = FX(YMIN);
  745.             p1->y = YMIN;
  746.         } else
  747.         if (p1->y > YMAX) {
  748.             p1->x = FX(YMAX);
  749.             p1->y = YMAX;
  750.         }
  751.         if (p1->x < XMIN) {
  752.             p1->y = FY(XMIN);
  753.             p1->x = XMIN;
  754.         } else
  755.         if (p1->x > XMAX) {
  756.             p1->y = FY(XMAX);
  757.             p1->x = XMAX;
  758.         }
  759. // printf("%d) new: %d %d %d %d\n",ct,p0->x,p0->y,p1->x,p1->y);
  760. //ct++;
  761.  
  762.         if (p0->x > XMAX || p0->x < XMIN) return;
  763.         if (p1->x > XMAX || p1->x < XMIN) return;
  764.         if (p0->y > YMAX || p0->y < YMIN) return;
  765.         if (p1->y > YMAX || p1->y < YMIN) return;
  766.  
  767. // Recalculate variations
  768.      dx = p1->x - p0->x;
  769.      dy = p1->y - p0->y;
  770.  
  771.      if (ABS(dx)<=ABS(dy)) {
  772.           if (dy<0) {
  773.                void *t;
  774.                t=p0;p0=p1;p1=t;
  775.                dy = -dy;
  776.                         dx = -dx;
  777.           }
  778.           dy++;
  779.           dx = I2F(dx)/dy;
  780.  
  781.           COLOR2LCOLOR(c0,p0->c);
  782.           COLOR2LCOLOR(c1,p1->c);
  783.           CALCDC(dc,c0,c1,dy);
  784.  
  785.           x = I2F(p0->x);
  786.           y = p0->y;
  787.  
  788.           p = vram + y*FRAME_W;
  789.           do {
  790.                p[F2I(x)] = LCOL2PIXEL(c0);
  791.                x+=dx;
  792.                ADDCOL(c0,dc);
  793.                p+=FRAME_W;
  794.           } while(--dy);
  795.  
  796.      } else {
  797.           int y;
  798.           if (dx<0) {
  799.                void *t;
  800.                t=p0;p0=p1;p1=t;
  801.                dx = -dx;
  802.                         dy = -dy;
  803.           }
  804.           dx++;
  805.           dy = I2F(dy)/dx;
  806.  
  807.           COLOR2LCOLOR(c0,p0->c);
  808.           COLOR2LCOLOR(c1,p1->c);
  809.           CALCDC(dc,c0,c1,dx);
  810.  
  811.           x = p0->x;
  812.           y = I2F(p0->y);
  813.  
  814.           p = vram+x;
  815.           do {
  816.                p[F2I(y)*FRAME_W] = LCOL2PIXEL(c0);
  817.                y+=dy;
  818.                ADDCOL(c0,dc);
  819.                p++;
  820.           } while(--dx);
  821.      }
  822.     toUpdate = 1;
  823. }
  824.  
  825. #define   FT_SHLINE() \
  826.                do { \
  827.                     int c = *p2++; \
  828.                     if (c) *p=c; \
  829.                     p++; \
  830.                } while(--dx)
  831.  
  832. #define   FT_SHLINE_A(ALPHA) \
  833.                do { \
  834.                     int c = *p2++; \
  835.                     if (c) { \
  836.                          if (c&0x8000) ALPHA(c,*p); \
  837.                          *p = c; \
  838.                     } \
  839.                     p++; \
  840.                } while(--dx)
  841.  
  842. #define   FT_SHLINE_A15(ALPHA) \
  843.                do { \
  844.                     int c = *p2++; \
  845.                     if (c) { \
  846.                          int c2 = MULCOL(c,c0); \
  847.                          if (c&0x8000) ALPHA(c2,*p); \
  848.                          *p = c2; \
  849.                     } \
  850.                     p++; \
  851.                } while(--dx)
  852.  
  853. void DrawSprite(Sprt *prim,int w,int h)
  854. {
  855.     INT16 *p0;
  856.     INT16 *tex;
  857.     int mode;
  858.     int x,y,u,v;
  859.     int tpage,clut;
  860.     COLOR c0code;
  861.     LCOLOR c0;
  862.  
  863.     x = prim->v.x + OFFX;
  864.     y = prim->v.y + OFFY;
  865.     u = prim->v.u;
  866.     v = prim->v.v;
  867.     clut = prim->v.pad;
  868.     tpage = gpu.tpage;
  869.     c0code = prim->c;
  870.  
  871.     if (x>XMAX || x+w<XMIN ||
  872.             y>YMAX || y+h<YMIN ||
  873.             w<=0       || h<=0) return;
  874.     if (x<XMIN)
  875.             {
  876.                 int dx=XMIN-x;
  877.                 if ((w-=dx) <= 0) return;
  878.                 u+=dx;
  879.                 x=XMIN;
  880.             }
  881.     else if (x+w>XMAX) {
  882.             if ((w=XMAX-x) <=0) return;
  883.         }
  884.     if (y<YMIN)
  885.             {
  886.                 int dy=YMIN-y;
  887.                 if ((h-=dy) <= 0) return;
  888.                 v+=dy;
  889.                 y=YMIN;
  890.             }
  891.     else if (y+h>YMAX) {
  892.             if ((h=YMAX-y) <= 0) return;
  893.         }
  894.  
  895.     p0 = vram+y*FRAME_W+x;
  896.  
  897.     tex = get_texture(tpage,clut);
  898.     mode = ((tpage>>5)&3)|((c0code.code&3)*16);
  899.         vramchange(x,y,x+w,y+h);
  900.  
  901.         if (!(mode&NOSHADE))
  902.             COLOR2LCOLOR(c0,c0code);
  903.  
  904.     do {
  905.         INT16 *p = p0;
  906.         INT16 *p2 = &tex[u+v*256];
  907.         int dx = w;
  908.  
  909.         switch(mode) {
  910.         case 0:
  911.             do {
  912.                 int c = *p2++;
  913.                 if (c) *p=MULCOL(c,c0);
  914.                 p++;
  915.             } while(--dx);
  916.                 break;
  917.         case T50|NOSHADE:
  918.             FT_SHLINE_A(ALPHA50);
  919.             break;
  920.         case T100|NOSHADE:
  921.             FT_SHLINE_A(ALPHA100);
  922.             break;
  923.         case T100m|NOSHADE:
  924.             FT_SHLINE_A(ALPHA100m);
  925.             break;
  926.         case T25|NOSHADE:
  927.             FT_SHLINE_A(ALPHA25);
  928.             break;
  929.  
  930.         case T50:
  931.             FT_SHLINE_A15(ALPHA50);
  932.             break;
  933.         case T100:
  934.             FT_SHLINE_A15(ALPHA100);
  935.             break;
  936.         case T100m:
  937.             FT_SHLINE_A15(ALPHA100m);
  938.             break;
  939.         case T25:
  940.             FT_SHLINE_A15(ALPHA25);
  941.             break;
  942.         default:
  943.             FT_SHLINE();
  944.             break;
  945.         }
  946.         v++;
  947.         p0+=FRAME_W;
  948.     } while(--h);
  949. }
  950.  
  951. void DrawPixel(int x,int y,int c)
  952. {
  953.     x+=OFFX;
  954.     y+=OFFY;
  955.     if (x>=XMIN && x<=XMAX && y>=YMIN && y<=YMAX)
  956.     {
  957.         vram[y*FRAME_W+x]=c;
  958.         vramchange(x,y,x+1,y+1);
  959.     }
  960. }
  961.  
  962. void DrawBoxNoClip(int x,int y,int w,int h,int c)
  963. {
  964.     INT16 *p0;
  965.  
  966.     if (x>1023 || y>511) return;
  967.     if (x<0) {
  968.         w += x; x = 0;
  969.     }
  970.     if (y<0) {
  971.         h += y; y = 0;
  972.     }
  973.  
  974.     if (w<=0 || h<=0) return;
  975.     if (x+w > 1023) w = 1023-x;
  976.     if (y+h > 511) h = 511-y;
  977.     vramchange(x,y,x+w,y+h);
  978.  
  979.     p0 = &vram[y*FRAME_W+x];
  980.     c = (c<<16)|c;
  981.     do {
  982.         _hline(p0,w,c);
  983.         p0+=FRAME_W;
  984.     } while(--h);
  985. }
  986.  
  987. void DrawBoxShaded(int x,int y,int w,int h, COLOR c)
  988. {
  989.     INT16 *p0,*p;
  990.      LCOLOR c0;
  991.      int    dx;
  992.  
  993.     if (x>1023 || y>511) return;
  994.     if (x<0) {
  995.         w += x; x = 0;
  996.     }
  997.     if (y<0) {
  998.         h += y; y = 0;
  999.     }
  1000.  
  1001.     if (w<=0 || h<=0) return;
  1002.     if (x+w > 1023) w = 1023-x;
  1003.     if (y+h > 511) h = 511-y;
  1004.  
  1005.     vramchange(x,y,x+w,y+h);
  1006.     p0 = &vram[y*FRAME_W+x];
  1007.     c.r = ~c.r; c.g = ~c.g; c.b = ~c.b; 
  1008.     COLOR2LCOLOR(c0, c);
  1009.      
  1010.     do{
  1011.           p = p0;
  1012.           dx = w;
  1013.           do {
  1014.                *p=MULCOL(*p,c0);
  1015.                p++;
  1016.           } while(--dx);
  1017.  
  1018.         p0+=FRAME_W;
  1019.     } while(--h);
  1020. }
  1021.  
  1022. void DrawTile(Tile *prim,int w,int h)
  1023. {
  1024.     int x,y;
  1025.  
  1026.     x = prim->v.x + OFFX;
  1027.     y = prim->v.y + OFFY;
  1028.  
  1029.     if (x>XMAX || x+w<XMIN ||
  1030.         y>YMAX || y+h<YMIN ||
  1031.         w<=0   || h<=0) return;
  1032.     if (x<XMIN) x=XMIN;
  1033.     else if (x+w>XMAX) w=XMAX-x;
  1034.     if (y<YMIN) y=YMIN;
  1035.     else if (y+h>YMAX) h=YMAX-y;
  1036.  
  1037.      if ((prim->c.code & 2) == 0)
  1038.           DrawBoxNoClip(x,y,w,h,COLOR2PIXEL(prim->c));
  1039.      else
  1040.           DrawBoxShaded(x,y,w,h,prim->c);
  1041. }
  1042.  
  1043.  
  1044. void move(int x0,int y0,int x1,int y1,int w,int h)
  1045. {
  1046.      INT16 *from = VRAMADR(x0,y0);
  1047.      INT16 *to   = VRAMADR(x1,y1);
  1048.  
  1049. // printf("x0=%d y0=%d x1=%d y1=%d w=%d h=%d\n",x0,y0,x1,y1,w,h);
  1050.         if (w<=0 || h<=0) return;
  1051.         if (x0+w > 1023) w = 1023 - x0;
  1052.         if (x1+w > 1023) w = 1023 - x1;
  1053.         if (y0+h > 511) h = 511 - y0;
  1054.         if (y1+h > 511) h = 511 - y1;
  1055.     vramchange(x1,y1,x1+w,y1+h);
  1056.      if (from>to) {
  1057.           do {
  1058.                memcpy(to,from,w*2);
  1059.                from += FRAME_W;
  1060.                to += FRAME_W;
  1061.           } while(--h);
  1062.      } else {
  1063.           from += FRAME_W*h;
  1064.           to += FRAME_W*h;
  1065.           do {
  1066.                from -= FRAME_W;
  1067.                to -= FRAME_W;
  1068.                memmove(to,from,w*2);
  1069.           } while(--h);
  1070.      }
  1071. }
  1072.  
  1073. #define   MINMAX(N,nn) \
  1074.      {int xmin,xmax,i; \
  1075.      xmin = xmax = v[0].x; \
  1076.      ymin = ymax = v[0].y; \
  1077.      for (i=1;i<N;i++) { \
  1078.           if      (xmin>v[i].x) xmin = v[i].x; \
  1079.           else if (xmax<v[i].x) xmax = v[i].x; \
  1080.           if      (ymin>v[i].y) ymin = v[i].y; \
  1081.           else if (ymax<v[i].y) ymax = v[i].y; \
  1082.      } \
  1083.      if (xmax==xmin || xmin>=XMAX || xmax<XMIN) return nn; }\
  1084.      if (ymax==ymin || ymin>=YMAX || ymax<YMIN) return nn; \
  1085.      if (ymin<YMIN) ymin=YMIN; \
  1086.      if (ymax>YMAX) ymax=YMAX;
  1087. #define   MINMAX3(nn)    MINMAX(3,nn)
  1088. #define   MINMAX4(nn)    MINMAX(4,nn)
  1089.  
  1090. //--------------------------------------------------------------------------
  1091.  
  1092. int gpu_polyF3(PolyF3 *prim)
  1093. {
  1094.     int ymin,ymax;
  1095.     POINT_F v[3];
  1096.  
  1097.     memcpy(v,prim->v,sizeof(v));
  1098.     v[0].x += OFFX;
  1099.     v[0].y += OFFY;
  1100.     v[1].x += OFFX;
  1101.     v[1].y += OFFY;
  1102.     v[2].x += OFFX;
  1103.     v[2].y += OFFY;
  1104.  
  1105. #if SYSLOGOUT==1
  1106.     syslog("F3 code=%08x (%d,%d)-(%d,%d)-(%d,%d)",
  1107.         *(UINT32 *)&prim->c, v[0].x, v[0].y, v[1].x, v[1].y,
  1108.         v[2].x, v[2].y);
  1109. #endif
  1110.  
  1111.     if (v[0].x*(v[1].y-v[2].y) + v[1].x*(v[2].y-v[0].y) + v[2].x*(v[0].y-v[1].y)<0) {
  1112.         POINT_F tmp;
  1113.         tmp = v[1]; v[1]=v[2]; v[2]=tmp;
  1114.     }
  1115.  
  1116.     MINMAX3(NbF3);
  1117.     EdgeF(&v[0],&v[1],edge);
  1118.     EdgeF(&v[1],&v[2],edge);
  1119.     EdgeF(&v[2],&v[0],edge);
  1120.     DrawF(edge,ymin,ymax,COLOR2PIXEL(prim->c));
  1121.  
  1122.     return NbF3;
  1123. }
  1124.  
  1125. int gpu_polyF4(PolyF4 *prim)
  1126. {
  1127.     int ymin,ymax;
  1128.     POINT_F v[4];
  1129.  
  1130.     memcpy(v,prim->v,sizeof(v));
  1131.     v[0].x += OFFX;
  1132.     v[0].y += OFFY;
  1133.     v[1].x += OFFX;
  1134.     v[1].y += OFFY;
  1135.     v[2].x += OFFX;
  1136.     v[2].y += OFFY;
  1137.     v[3].x += OFFX;
  1138.     v[3].y += OFFY;
  1139.  
  1140. #if SYSLOGOUT==1
  1141.     syslog("F4 code=%08x (%d,%d)-(%d,%d)-(%d,%d)-(%d,%d)",
  1142.         *(UINT32 *)&prim->c, v[0].x, v[0].y, v[1].x, v[1].y,
  1143.         v[2].x, v[2].y, v[3].x, v[3].y);
  1144. #endif
  1145.  
  1146.     MINMAX4(NbF4);
  1147.     EdgeF(&v[0],&v[1],edge);
  1148.     EdgeF(&v[1],&v[3],edge);
  1149.     EdgeF(&v[3],&v[2],edge);
  1150.     EdgeF(&v[2],&v[0],edge);
  1151.     DrawF(edge,ymin,ymax,COLOR2PIXEL(prim->c));
  1152.  
  1153.     return NbF4;
  1154. }
  1155.  
  1156. int gpu_polyG3(PolyG3 *prim)
  1157. {
  1158.     int ymin,ymax;
  1159.     POINT_G v[3];
  1160.  
  1161.     memcpy(v,prim->v,sizeof(v));
  1162.  
  1163.     v[0].x += OFFX;
  1164.     v[0].y += OFFY;
  1165.     v[1].x += OFFX;
  1166.     v[1].y += OFFY;
  1167.     v[2].x += OFFX;
  1168.     v[2].y += OFFY;
  1169.  
  1170. #if SYSLOGOUT==1
  1171.     syslog("G3 code=%08x (%d,%d)-(%d,%d)-(%d,%d)",
  1172.         *(UINT32 *)&prim->v[0].c, v[0].x, v[0].y, v[1].x, v[1].y,
  1173.         v[2].x, v[2].y);
  1174. #endif
  1175.  
  1176.     if (v[0].x*(v[1].y-v[2].y) + v[1].x*(v[2].y-v[0].y) + v[2].x*(v[0].y-v[1].y)<0) {
  1177.         POINT_G tmp;
  1178.         tmp = v[1]; v[1]=v[2]; v[2]=tmp;
  1179.     }
  1180.     MINMAX3(NbG3);
  1181.     EdgeG(&v[0],&v[1],edge);
  1182.     EdgeG(&v[1],&v[2],edge);
  1183.     EdgeG(&v[2],&v[0],edge);
  1184.     DrawG(edge,ymin,ymax,prim->v[0].c.code);
  1185.  
  1186.     return NbG3;
  1187. }
  1188.  
  1189. int gpu_polyG4(PolyG4 *prim)
  1190. {
  1191.     int ymin,ymax;
  1192.     POINT_G v[4];
  1193.  
  1194.     memcpy(v,prim->v,sizeof(v));
  1195.  
  1196.     v[0].x += OFFX;
  1197.     v[0].y += OFFY;
  1198.     v[1].x += OFFX;
  1199.     v[1].y += OFFY;
  1200.     v[2].x += OFFX;
  1201.     v[2].y += OFFY;
  1202.     v[3].x += OFFX;
  1203.     v[3].y += OFFY;
  1204.  
  1205. #if SYSLOGOUT==1
  1206.     syslog("G4 code=%08x (%d,%d)-(%d,%d)-(%d,%d)-(%d,%d)",
  1207.         *(UINT32 *)&prim->v[0].c, v[0].x, v[0].y, v[1].x, v[1].y,
  1208.         v[2].x, v[2].y, v[3].x, v[3].y);
  1209. #endif
  1210.  
  1211.     if (v[0].x*(v[1].y-v[2].y) + v[1].x*(v[2].y-v[0].y) + v[2].x*(v[0].y-v[1].y)<0) {
  1212.         POINT_G tmp;
  1213.         tmp = v[1]; v[1]=v[2]; v[2]=tmp;
  1214.     }
  1215.     MINMAX4(NbG4);
  1216.     EdgeG(&v[0],&v[1],edge);
  1217.     EdgeG(&v[1],&v[3],edge);
  1218.     EdgeG(&v[3],&v[2],edge);
  1219.     EdgeG(&v[2],&v[0],edge);
  1220.     DrawG(edge,ymin,ymax,prim->v[0].c.code);
  1221.  
  1222.     return NbG4;
  1223. }
  1224.  
  1225. int gpu_polyFT3(PolyFT3 *prim)
  1226. {
  1227.     int ymin,ymax;
  1228.     POINT_FT v[3];
  1229.  
  1230.     memcpy(v,prim->v,sizeof(v));
  1231.  
  1232.     v[0].x += OFFX;
  1233.     v[0].y += OFFY;
  1234.     v[1].x += OFFX;
  1235.     v[1].y += OFFY;
  1236.     v[2].x += OFFX;
  1237.     v[2].y += OFFY;
  1238.  
  1239. #if SYSLOGOUT==1
  1240.     syslog("FT3 code=%08x (%d,%d)-(%d,%d)-(%d,%d)",
  1241.         *(UINT32 *)&prim->c, v[0].x, v[0].y, v[1].x, v[1].y,
  1242.         v[2].x, v[2].y);
  1243. #endif
  1244.  
  1245.     if (v[0].x*(v[1].y-v[2].y) + v[1].x*(v[2].y-v[0].y) + v[2].x*(v[0].y-v[1].y)<0) {
  1246.         POINT_FT tmp;
  1247.         tmp = v[1]; v[1]=v[2]; v[2]=tmp;
  1248.     }
  1249.     MINMAX3(NbFT3);
  1250.     EdgeFT(&v[0],&v[1],edge);
  1251.     EdgeFT(&v[1],&v[2],edge);
  1252.     EdgeFT(&v[2],&v[0],edge);
  1253.     DrawFT(edge,ymin,ymax,prim->v[1].pad,prim->v[0].pad,prim->c);
  1254.  
  1255.     return NbFT3;
  1256. }
  1257.  
  1258. int gpu_polyFT4(PolyFT4 *prim)
  1259. {
  1260.     int ymin,ymax;
  1261.     POINT_FT v[4];
  1262.  
  1263.     memcpy(v,prim->v,sizeof(v));
  1264.  
  1265.     v[0].x += OFFX;
  1266.     v[0].y += OFFY;
  1267.     v[1].x += OFFX;
  1268.     v[1].y += OFFY;
  1269.     v[2].x += OFFX;
  1270.     v[2].y += OFFY;
  1271.     v[3].x += OFFX;
  1272.     v[3].y += OFFY;
  1273.  
  1274. #if SYSLOGOUT==1
  1275.     syslog("FT4 code=%08x (%d,%d)-(%d,%d)-(%d,%d)-(%d,%d)",
  1276.         *(UINT32 *)&prim->c, v[0].x, v[0].y, v[1].x, v[1].y,
  1277.         v[2].x, v[2].y, v[3].x, v[3].y);
  1278. #endif
  1279.  
  1280.     if (v[0].x*(v[1].y-v[2].y) + v[1].x*(v[2].y-v[0].y) + v[2].x*(v[0].y-v[1].y)<0) {
  1281.         POINT_FT tmp;
  1282.         tmp = v[1]; v[1]=v[2]; v[2]=tmp;
  1283.     }
  1284.     MINMAX4(NbFT4);
  1285.     EdgeFT(&v[0],&v[1],edge);
  1286.     EdgeFT(&v[1],&v[3],edge);
  1287.     EdgeFT(&v[3],&v[2],edge);
  1288.     EdgeFT(&v[2],&v[0],edge);
  1289.     DrawFT(edge,ymin,ymax,prim->v[1].pad,prim->v[0].pad,prim->c);
  1290.  
  1291.     return NbFT4;
  1292. }
  1293.  
  1294. int gpu_polyGT3(PolyGT3 *prim)
  1295. {
  1296.     int ymin,ymax;
  1297.     POINT_GT v[3];
  1298.  
  1299.     memcpy(v,prim->v,sizeof(v));
  1300.  
  1301.     v[0].x += OFFX;
  1302.     v[0].y += OFFY;
  1303.     v[1].x += OFFX;
  1304.     v[1].y += OFFY;
  1305.     v[2].x += OFFX;
  1306.     v[2].y += OFFY;
  1307.  
  1308. #if SYSLOGOUT==1
  1309.     syslog("GT3 code=%08x (%d,%d)-(%d,%d)-(%d,%d)",
  1310.         *(UINT32 *)&prim->v[0].c, v[0].x, v[0].y, v[1].x, v[1].y,
  1311.         v[2].x, v[2].y);
  1312. #endif
  1313.  
  1314.     if (v[0].x*(v[1].y-v[2].y) + v[1].x*(v[2].y-v[0].y) + v[2].x*(v[0].y-v[1].y)<0) {
  1315.         POINT_GT tmp;
  1316.         tmp = v[1]; v[1]=v[2]; v[2]=tmp;
  1317.     }
  1318.     MINMAX3(NbGT3);
  1319.     EdgeGT(&v[0],&v[1],edge);
  1320.     EdgeGT(&v[1],&v[2],edge);
  1321.     EdgeGT(&v[2],&v[0],edge);
  1322.     DrawGT(edge,ymin,ymax,prim->v[1].pad,prim->v[0].pad,prim->v[0].c.code);
  1323.  
  1324.     return NbGT3;
  1325. }
  1326.  
  1327. int gpu_polyGT4(PolyGT4 *prim)
  1328. {
  1329.     int ymin,ymax;
  1330.     POINT_GT v[4];
  1331.  
  1332.     memcpy(v,prim->v,sizeof(v));
  1333.  
  1334.     v[0].x += OFFX;
  1335.     v[0].y += OFFY;
  1336.     v[1].x += OFFX;
  1337.     v[1].y += OFFY;
  1338.     v[2].x += OFFX;
  1339.     v[2].y += OFFY;
  1340.     v[3].x += OFFX;
  1341.     v[3].y += OFFY;
  1342.  
  1343. #if SYSLOGOUT==1
  1344.     syslog("GT4 code=%08x (%d,%d)-(%d,%d)-(%d,%d)-(%d,%d)",
  1345.         *(UINT32 *)&prim->v[0].c, v[0].x, v[0].y, v[1].x, v[1].y,
  1346.         v[2].x, v[2].y, v[3].x, v[3].y);
  1347. #endif
  1348.  
  1349.     if (v[0].x*(v[1].y-v[2].y) + v[1].x*(v[2].y-v[0].y) + v[2].x*(v[0].y-v[1].y)<0) {
  1350.         POINT_GT tmp;
  1351.         tmp = v[1]; v[1]=v[2]; v[2]=tmp;
  1352.     }
  1353.     MINMAX4(NbGT4);
  1354.     EdgeGT(&v[0],&v[1],edge);
  1355.     EdgeGT(&v[1],&v[3],edge);
  1356.     EdgeGT(&v[3],&v[2],edge);
  1357.     EdgeGT(&v[2],&v[0],edge);
  1358.     DrawGT(edge,ymin,ymax,prim->v[1].pad,prim->v[0].pad,prim->v[0].c.code);
  1359. //    DrawFT(edge,ymin,ymax,prim->v[1].pad,prim->v[0].pad,prim->v[0].c);
  1360.  
  1361.     return NbGT4;
  1362. }
  1363.  
  1364. int gpu_lineF2(LineF2 *prim)
  1365. {
  1366.     POINT_F v[2];
  1367.  
  1368.     memcpy(v,prim->v,sizeof(v));
  1369.  
  1370.     v[0].x += OFFX;
  1371.     v[0].y += OFFY;
  1372.     v[1].x += OFFX;
  1373.     v[1].y += OFFY;
  1374.  
  1375. #if SYSLOGOUT==1
  1376.     syslog("LineG code=%08x (%d,%d)-(%d,%d)",
  1377.         *(UINT32 *)&prim->c, v[0].x, v[0].y, v[1].x, v[1].y);
  1378. #endif
  1379.  
  1380.     DrawLineF(&v[0],&v[1],COLOR2PIXEL(prim->c));
  1381.  
  1382.     return NbF2;
  1383. }
  1384.  
  1385. int gpu_lineF(LineF3 *prim)
  1386. {
  1387. return 5;
  1388. /*
  1389.     POINT_F v[2],*vv;
  1390.     int     n=3;
  1391.  
  1392.     v[0] = prim->v[0];
  1393.     v[0].x += OFFX;
  1394.     v[0].y += OFFY;
  1395.     vv = prim->v + 1;
  1396.     while (*(UINT32 *)(vv) != 0x55555555)
  1397.     {
  1398.         v[1] = *vv;
  1399.         v[1].x += OFFX;
  1400.         v[1].y += OFFY;
  1401.  
  1402. #if SYSLOGOUT==1
  1403.         syslog("LineG code=%08x (%d,%d)-(%d,%d)",
  1404.             *(UINT32 *)&prim->c, v[0].x, v[0].y, v[1].x, v[1].y);
  1405. #endif
  1406.  
  1407.         DrawLineF(&v[0],&v[1],COLOR2PIXEL(prim->c));
  1408.         v[0] = v[1];
  1409.         vv++;
  1410.         n++;
  1411.     }
  1412.  
  1413.     return n;
  1414. */
  1415. }
  1416.  
  1417. int gpu_lineG2(LineG2 *prim)
  1418. {
  1419.     POINT_G v[2];
  1420.  
  1421.     memcpy(v,prim->v,sizeof(v));
  1422.  
  1423.     v[0].x += OFFX;
  1424.     v[0].y += OFFY;
  1425.     v[1].x += OFFX;
  1426.     v[1].y += OFFY;
  1427.  
  1428. #if SYSLOGOUT==1
  1429.     syslog("LineG code=%08x (%d,%d)-(%d,%d)",
  1430.         *(UINT32 *)&prim->c, v[0].x, v[0].y, v[1].x, v[1].y);
  1431. #endif
  1432.  
  1433.     DrawLineG(&v[0],&v[1]);
  1434.  
  1435.     return NbG2;
  1436. }
  1437.  
  1438. int gpu_lineG(LineG3 *prim)
  1439. {
  1440. return 7;
  1441. /*
  1442.     POINT_G v[2],*vv;
  1443.     int     n=4;
  1444.  
  1445.     v[0] = prim->v[0];
  1446.     v[0].x += OFFX;
  1447.     v[0].y += OFFY;
  1448.     vv = prim->v + 1;
  1449.     while (*(UINT32 *)(vv) != 0x55555555)
  1450.     {
  1451.         v[1] = *vv;
  1452.         v[1].x += OFFX;
  1453.         v[1].y += OFFY;
  1454.  
  1455. #if SYSLOGOUT==1
  1456.         syslog("LineG code=%08x (%d,%d)-(%d,%d)",
  1457.             *(UINT32 *)&prim->c, v[0].x, v[0].y, v[1].x, v[1].y);
  1458. #endif
  1459.  
  1460.         DrawLineG(&v[0],&v[1]);
  1461.         v[0] = v[1];
  1462.         vv++;
  1463.         n+=2;
  1464.     }
  1465.  
  1466.     return n;
  1467. */
  1468. }
  1469.  
  1470. int gpu_fill(Fill *prim)
  1471. {
  1472. #if SYSLOGOUT==1
  1473.     syslog("FILL code=%08x (%d,%d) w=%d h=%d",
  1474.         *(UINT32 *)&prim->c,prim->v.x,prim->v.y,prim->w,prim->h);
  1475. #endif
  1476.  
  1477.     DrawBoxNoClip(prim->v.x,prim->v.y,prim->w,prim->h,COLOR2PIXEL(prim->c));
  1478.  
  1479.     return NbFILL;
  1480. }
  1481.  
  1482. int gpu_tile(Tile *prim)
  1483. {
  1484. #if SYSLOGOUT==1
  1485.     syslog("TILE code=%08x (%d,%d) w=%d h=%d",
  1486.         *(UINT32 *)&prim->c,prim->v.x,prim->v.y,prim->w,prim->h);
  1487. #endif
  1488.  
  1489.     DrawTile(prim,prim->w,prim->h);
  1490.  
  1491.     return NbFILL;
  1492. }
  1493.  
  1494. int gpu_tile8(Tile8 *prim)
  1495. {
  1496. #if SYSLOGOUT==1
  1497.     syslog("TILE8 code=%08x (%d,%d)",
  1498.         *(UINT32 *)&prim->c,prim->v.x,prim->v.y);
  1499. #endif
  1500.  
  1501.     DrawTile((Tile *)prim,8,8);
  1502.  
  1503.     return NbTILEx;
  1504. }
  1505.  
  1506. int gpu_tile16(Tile16 *prim)
  1507. {
  1508. #if SYSLOGOUT==1
  1509.     syslog("TILE16 code=%08x (%d,%d)",
  1510.         *(UINT32 *)&prim->c,prim->v.x,prim->v.y);
  1511. #endif
  1512.  
  1513.     DrawTile((Tile *)prim,16,16);
  1514.  
  1515.     return NbTILEx;
  1516. }
  1517.  
  1518. int gpu_tile1(Tile1 *prim)
  1519. {
  1520. #if SYSLOGOUT==1
  1521.     syslog("TILE1 code=%08x (%d,%d)",
  1522.         *(UINT32 *)&prim->c,prim->v.x,prim->v.y);
  1523. #endif
  1524.  
  1525.     DrawPixel(prim->v.x,prim->v.y,COLOR2PIXEL(prim->c));
  1526.  
  1527.     return NbTILEx;
  1528. }
  1529.  
  1530.  
  1531. int gpu_sprt(Sprt *prim)
  1532. {
  1533. #if SYSLOGOUT==1
  1534.     syslog("Sprite code=%08x (%d,%d) w=%d h=%d",
  1535.         *(UINT32 *)&prim->c,prim->v.x,prim->v.y,prim->w,prim->h);
  1536. #endif
  1537.  
  1538.     DrawSprite(prim,prim->w,prim->h);
  1539.  
  1540.     return NbSPRT;
  1541. }
  1542.  
  1543. int gpu_sprt8(Sprt *prim)
  1544. {
  1545. #if SYSLOGOUT==1
  1546.     syslog("Sprite8 code=%08x (%d,%d)",
  1547.         *(UINT32 *)&prim->c,prim->v.x,prim->v.y);
  1548. #endif
  1549.  
  1550.     DrawSprite(prim,8,8);
  1551.  
  1552.     return NbSPRTx;
  1553. }
  1554.  
  1555. int gpu_sprt16(Sprt *prim)
  1556. {
  1557. #if SYSLOGOUT==1
  1558.     syslog("Sprite16 code=%08x (%d,%d)",
  1559.         *(UINT32 *)&prim->c,prim->v.x,prim->v.y);
  1560. #endif
  1561.  
  1562.     DrawSprite(prim,16,16);
  1563.  
  1564.     return NbSPRTx;
  1565. }